package com.hc.kotlin_coroutine

import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.async
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
import kotlinx.coroutines.withTimeoutOrNull
import java.lang.Exception
import kotlin.system.measureTimeMillis

fun main11() = runBlocking<Unit> {
    var job = launch {
        try {
            repeat(20){
                delay(500)
                println("sleeping ${it}")
            }
        }finally {
            //delay(1000)//finally执行挂起函数会抛出异常
            withContext(NonCancellable){//finally中使用挂起函数
                delay(1000)
            }
            println("finally")
        }
    }
    delay(1300)
    println("try to cancel")
    job.cancelAndJoin()
    println("quit")
}
fun main12() = runBlocking<Unit>{
//    withTimeout(1300){//超时抛异常
//        repeat(50){
//            delay(500)
//            println("sleeping ${it}")
//        }
//    }
    val result = withTimeoutOrNull(1300) {  //超时不抛异常
        repeat(50) {
            delay(500)
            println("sleeping ${it}")
        }
        "OK"
    }
    println(result?:"TimeOut")
}
var acquired = 0
class Resource{
    init {
        acquired++
    }
    fun close(){
        acquired--
    }
}
fun main13() = runBlocking {
    repeat(10000){
        launch {  //不能保证一定输出为0
            val resource = withTimeout(60){
                delay(59)
                Resource()
            }
            resource.close()
        }
//        launch {//保证一定输出为0
//            var resource:Resource?=null
//            try {
//                withTimeout(60){
//                    delay(50)
//                    resource = Resource()
//                }
//            }finally {
//                resource?.close()
//            }
//        }
    }
    println(acquired)
}
fun main() = runBlocking<Unit> {
//    var job = launch {
//        var i = doOne()
//        println(i)
//    }
//    delay(500)
//    job.cancel()
//    println("quit")

//    val time = measureTimeMillis {
//        var one = doOne() //串行
//        var two = doTwo()
//        println("result = ${one+two}")
//    }

//    val time = measureTimeMillis {
//        var one = async {  doOne()} //并行
//        var two = async {  doTwo()}
//        println("result = ${one.await()+two.await()}")
//    }

    val time = measureTimeMillis {
        var one = async (start = CoroutineStart.LAZY){  doOne()} //懒惰并行
        var two = async (start = CoroutineStart.LAZY){  doTwo()}
        one.start() //不调用则是串行
        two.start()
        println("result = ${one.await()+two.await()}")
    }
    println("time = ${time}")
}
suspend fun doOne():Int{ //挂起函数是可被取消的
    delay(1000)
    return 10
}
suspend fun doTwo():Int{
    delay(1000)
    return 15
}